<!DOCTYPE html>
<html lang="zh-ch">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <input type="text" id="input">
  <br>
  <br>
  <button id="btn" onclick="btn()">按钮</button>
  <button id="btn" onclick="show()">按钮显示data</button>
  <button id="btn" onclick="showArr()">按钮显示Arr</button>
</body>
<script>
  const data = { text: '', text2: '' }
  // const data = {text: ''}


  //创建data的代理对象
  const proxyData = new Proxy(data, {
    //拦截对象属性的读取
    get(target, prop) {
      console.log('get :>> ', 'get');
      console.log('target :>> ', target);
      console.log('prop :>> ', prop);
      return target[prop]
    },
    //拦截对象属性的设置
    set(target, prop, value) {
      console.log('set :>> ', 'set');
      console.log('target :>> ', target);
      console.log('prop :>> ', prop);
      console.log('value :>> ', value);
      document.getElementById('input').value = value
      target[prop] = value
    }
  })

  //监听input的输入
  document.getElementById('input').addEventListener('input', function (e) {
    proxyData.text = e.target.value
  })


  function btn() {
    console.log('按钮被点击了')
    proxyData.text = '按钮被点击了'
  }
  function show() {
    console.log('data :>> ', data);
    console.log('proxyData :>> ', proxyData);
    console.log('text :>> ', proxyData.text);
  }


  const arr = [
    { name: '张三', age: 18 },
    { name: '李四', age: 19 }
  ]

  const handler = {
    // 拦截设置属性值的操作
    set(target, prop, value, receiver) {
      console.log('target :>> ', target);
      console.log('prop :>> ', prop);
      console.log('value :>> ', value);
      console.log('receiver :>> ', receiver);
      const exists = prop in target;
      let oldValue = exists ? target[prop] : undefined;

      // 如果属性存在且值改变，或者新属性被设置
      if (exists && value !== oldValue || !exists) {
        console.log(`变更: 索引 ${prop}, 旧值: ${oldValue}, 新值: ${value}`);
      }

      // 调用 Reflect.set 以确保原生行为
      const result = Reflect.set(...arguments);

      // 如果是长度变化，可能是数组方法引起的变动
      if (prop === 'length') {
        // 可以进一步处理，例如检查数组项是否被移除
        const removed = target.length < oldValue;
        if (removed) {
          const lastRemoved = oldValue - target.length;
          console.log(`数组长度减少, 移除索引: ${lastRemoved}`);
        }
      }
      return result;
    },
    // 拦截删除属性的操作
    deleteProperty(target, prop) {
      if (prop in target) {
        const oldValue = target[prop];
        console.log(`删除: 索引 ${prop}, 值: ${oldValue}`);
      }
      const result = Reflect.deleteProperty(target, prop);
      return result;
    },
  };

  const proxyArr = new Proxy(arr, handler)

  function showArr() {
    proxyArr[0].name = '王五'
    console.log('proxyArr :>> ', proxyArr);
  }

</script>

</html>